package com.xxx.blog.service.impl;

import com.github.pagehelper.PageHelper;
import com.xxx.blog.domain.ArticleType;
import com.xxx.blog.mapper.ArticleTypeMapper;
import com.xxx.blog.query.ArticleTypeQuery;
import com.xxx.blog.service.IArticleTypeService;
import com.xxx.blog.vo.ArticleTypeVo;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ArticleTypeServiceImpl implements IArticleTypeService {

    @Autowired
    private ArticleTypeMapper articleTypeMapper;
    //
    //@Autowired
    //private RedisTemplate redisTemplate;

    @Override
    public List<ArticleType> findAll() {
        return articleTypeMapper.findAll();
    }

    @Override
    public ArticleType findById(long id) {
        return articleTypeMapper.findById(id);
    }

    @Override
    public List<ArticleType> queryPage(ArticleTypeQuery articleTypeQuery) {
        PageHelper.startPage(articleTypeQuery.getCurrentPage(), articleTypeQuery.getPageSize());
        return articleTypeMapper.queryPage(articleTypeQuery);
    }

    @Override
    //@CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void addArticleType(ArticleType articleType) {
        ////保持缓存的一致性,使用延迟双删
        //redisTemplate.delete("typeTree");//第一次删除
        //
        //try {
        //    Thread.sleep(2000);//模仿别人操作耗时,延时时间
        //} catch (InterruptedException e) {
        //    e.printStackTrace();
        //}
        //redisTemplate.delete("typeTree");//第二次删除
        articleTypeMapper.addArticleType(articleType);
    }

    @Override
    //@CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void updateArticleType(ArticleType articleType) {
        articleType.setUpdateTime(new Date());
        articleTypeMapper.updateArticleType(articleType);
    }

    @Override
    //@CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void deleteArticleType(Long id) {
        articleTypeMapper.deleteArticleType(id);
    }

    @Override
    //@CacheEvict(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public void batchArticleType(Long[] ids) {
        articleTypeMapper.batchArticleType(ids);
    }

    @Override
    //@Cacheable(cacheNames = "articleType", key = "'typeTree'")//''要加,这是spring的spel表达式的要求!
    public List<ArticleType> getTypeTree(Long id) {
        //List<ArticleType> articleTypes = (List<ArticleType>) redisTemplate.boundValueOps("typeTree").get();//假设法
        //
        //if (articleTypes != null) {//如果redis中有就使用redis的
        //    System.out.println("数据来自redis");
        //    return articleTypes;
        //}
        //
        //System.out.println("数据来自mysql");
        //articleTypes=this.getArticleTypes(id);//否则查询mysql,然后存一份到redis下次就有了
        //redisTemplate.boundValueOps("typeTree").set(articleTypes);
        //
        //return articleTypes;

        return this.getArticleTypes(id);
    }

    @NotNull
    private List<ArticleType> getArticleTypes(Long id) {
        List<ArticleType> typeTree = new ArrayList<>();//类型树
        //调用findall方法查询所有的类型集合
        List<ArticleType> articleTypeList = articleTypeMapper.findAll();
        //准备一个map集合,目的直接通过id拿到找到类型对象
        Map<Long, ArticleType> map = new HashMap<>();
        //遍历循环,存入id与类型对象
        for (ArticleType articleType : articleTypeList) {
            map.put(articleType.getId(), articleType);
        }
        //遍历类型集合判断是否有父亲id
        for (ArticleType articleType : articleTypeList) {
            //对次id进行判断
            if(id.equals(articleType.getId())) {
                continue;
            }
            Long parentId = articleType.getParentId();
            //如果没有父id,说明它是一级直接存入集合
            if (parentId == null) {
                typeTree.add(articleType);
            }else{//在找到该类型的孩子存入集合
                ArticleType articleTypeParent = map.get(parentId);//如果有父id,则通过map集合当中的id找到该类型对象
                articleTypeParent.getChildren().add(articleType);//然后把该类型对象存入到父类型对象里面的孩子集合里面,
            }
        }

        return typeTree;
    }

    @Override
    public List<ArticleTypeVo> getArticleTypeStatistics() {
        return articleTypeMapper.getArticleTypeStatistics();
    }

}
